home *** CD-ROM | disk | FTP | other *** search
- {
- KAI ROHRBACHER
-
- > explain MODE X.
-
- Well, I don't care much about Mode X (which is 320x240x256), but use Mode Y
- (=320x200x256) --at least I think that this mode is called "Mode Y" (as far
- as I know, the terms were introduced by a series of Michael Abrash in "Dr.
- Dobb's Journal" (?)). Nevertheless, things are identical With the exception
- of initialising the VGA card! So here we go; note that the Asm code examples
- were taken from my ANIVGA-toolkit: the PASCAL-equivalents when given are "on
- the fly" Asm->PASCAL translations For improved clarity (I hope...); in
- doubt, rely on the Asm part.
-
- MODE Y in a nutshell
- ~~~~~~~~~~~~~~~~~~~~
-
- Basically, Mode Y works like this: use the BIOS to switch into normal
- 320x200x256 mode, then reProgram the sequencer to unchain the 4 bitplanes.
- This results in a bitplaned VRAM layout very similiar to the EGA/VGA's 16
- color modes:
- }
- Procedure InitGraph; Assembler;
- Asm
- MOV AX,0013h
- INT 10h
- MOV DX,03C4h
- MOV AL,04
- OUT DX,AL
- INC DX
- in AL,DX
- and AL,0F7h
- or AL,04
- OUT DX,AL
- MOV DX,03C4h
- MOV AL,02
- OUT DX,AL
- INC DX
- MOV AL,0Fh
- OUT DX,AL
- MOV AX,0A000h
- MOV ES,AX
- SUB DI,DI
- MOV AX,DI
- MOV CX,8000h
- CLD
- REP STOSW
-
- MOV DX,CrtAddress
- MOV AL,14h
- OUT DX,AL
- INC DX
- in AL,DX
- and AL,0BFh
- OUT DX,AL
- DEC DX
- MOV AL,17h
- OUT DX,AL
- INC DX
- in AL,DX
- or AL,40h
- OUT DX,AL
- end;
-
- {
- CrtAddress and StatusReg are the port addresses For the VGA ports needed;
- they are 3B4h and 3BAh on a monochrome display and 3D4h and 3DAh on a color
- display, but can be determined at run-time, too:
- }
-
- Asm
- MOV DX,3CCh
- in AL,DX
- TEST AL,1
- MOV DX,3D4h
- JNZ @L1
- MOV DX,3B4h
- @L1:
- MOV CrtAddress,DX
- ADD DX,6
- MOV StatusReg,DX
- end;
-
- {
- The VRAM layout is this: underneath each memory address in the range
- $A000:0000..$A000:$FFFF, there are 4 Bytes, each representing one pixel's
- color.
- Whenever you Write to or read from such an address, an internal logic of the
- VGA-card determines which one of those 4 pixels is accessed.
- A line of 320 pixels (=320 Bytes) thus only takes 320/4=80 Bytes address
- space, but to address a pixel, you need a) its VRAM address and b) which
- bitplane it's on.
- The pixels are arranged linearly: thus, the mapping from point coordinates
- to memory addresses is done by (x,y) <-> mem[$A000: y*80+ (x div 4)] and the
- bitplane is determined by (x mod 4).
- (Note coordinates start With 0 and that "div 4" can be computed very fast by
- "shr 2"; "mod 4" by "and 3").
-
- So you computed the proper address and bitplane. If you want to _read_ the
- pixel's color, you issue commands like this:
- portw[$3CE]:=(bitplane SHL 8)+4; color:=mem[$A000:y*80+(x shr 2)]
- Or For better speed & control, do it in Asm:
-
- MOV AL,4
- MOV AH,bitplane
- MOV DX,3CEh
- CLI
- OUT DX,AX
- MOV AL,ES:[DI]
- STI
-
- _Writing_ a pixel's color works similiar, but needs an additional step: the
- mask is computed by 1 SHL bitplane (that is: 1/2/4/8 For mod4 values 0/1/2/3
- respectively):
- portw[$3C4]:=(1 SHL bitplane+8)+2; mem[$A000:y*80+(x shr 2)]:=color
- Or using Asm again:
-
- MOV CL,bitplane
- MOV AH,1
- SHL AH,CL
- MOV AL,2
- MOV DX,3C4h
- CLI
- OUT DX,AX
- STOSB
- STI
-
- As stated above, one address represents 4 pixels, so 320x200 pixels occupy
- 16000 address Bytes. We do have 65536 (=$A000:0..$A000:$FFFF) though,
- therefore a bit more than 4 pages are possible. It's up to you to define
- your pages, 0..15999=page 0, 16000..31999=page 1, 32000..47999=page 2,
- 48000..63999=page 3, 64000..65535=unused is the most obvious layout.
-
- Which part of the VRAM is actually displayed can be Programmed by writing
- the offset part of the starting address to the Crt-controller (the segment
- part is implicitly set to $A000):
-
- Asm
- MOV DX,CrtAddress
- MOV AL,$0D
- CLI
- OUT DX,AL
- INC DX
- MOV AL,low Byte of starting offset
- OUT DX,AL
- DEC DX
- MOV AL,$0C
- OUT DX,AL
- INC DX
- MOV AL,high Byte of starting offset
- OUT DX,AL
- STI
- end;
-
- N.B.: if you reProgram the display's starting address more often than "every
- now and then", you better synchronize that to the vertical retrace or
- horizontal enable signal of your VGA card; otherwise, an annoying screen
- flicker will become visible during switching!
-
- For example, if you do a "FOR i:=1 to 100 do SetAddress(i*80)", this will
- result in a blinding fast hardware scroll: With each iteration of the loop,
- the display will start 80 address Bytes (=320 pixels = 1 row) later, giving
- the impression of the display scrolling upwards.
-
- Note that Mode X/Y do not differ in any other respect than their memory
- layouts from all the other bitplaned VGA modes: palette handling is the
- same, as is usage of the VGA's Write modes! In (default) Write mode 0, you
- can access the VRAM by Bytes, Words or dWords. Write mode 1 is handy to copy
- the contents of one Graphic page to another: you are restricted to Byte
- accesses, but each one will transfer 4 Bytes at once.
- For example, a sequence like the following...
- portw[$3C4]:=$0f02; portw[$3CE]:=$4105;
- move(mem[$a000:0000],mem[$a000:$3e80],16000);
- portw[$3CE]:=$4005
- ...enables all 4 planes, switches to Write mode 1, copies the (64000 Bytes)
- contents of the 2nd Graphic page to the 1st one and then switches back to
- Write mode 0 again.
- }